package com.jshoperxms.components.netease.nos;

import com.alibaba.fastjson.JSONObject;
import com.jshoperxms.Response;
import com.jshoperxms.components.upload.FileTools;
import com.jshoperxms.components.upload.qiniu.ImgFileBean;
import com.jshoperxms.controller.mall.backstage.base.BaseTController;
import com.jshoperxms.controller.utils.BaseTools;
import com.jshoperxms.controller.utils.DateTools;
import com.jshoperxms.controller.utils.statickey.StaticKey;
import com.jshoperxms.controller.utils.statickey.TagWords;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.netease.cloud.auth.BasicCredentials;
import com.netease.cloud.auth.Credentials;
import com.netease.cloud.services.nos.NosClient;
import com.netease.cloud.services.nos.model.*;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by sdywcd on 2018/3/12.
 * Des:
 */
@RestController
@RequestMapping("/netease/nos")
public class  NeteaseNosController extends BaseTController{


    @RequestMapping(value = "/getNosToken",method = RequestMethod.GET)
    public ResponseEntity getNosToken(@RequestParam String filename) {
        Map<String,Object> responsedata=new HashMap<>();
        String accessKey = NosKeys.ACCESSKEY;
        String secretKey = NosKeys.ACCESSSECRET;
        JSONObject putPolicy = new JSONObject();
        putPolicy.put("Bucket", NosKeys.BUCKET);
        putPolicy.put("Object", filename);
        putPolicy.put("Expires", 1893456000);//2030/12/31
        String encodedPutPolicy = new String(Base64.encodeBase64(putPolicy.toString().getBytes()));
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            //对签名字符串计算HMAC-SHA256签名
            String encodedSign = Base64.encodeBase64String(sha256_HMAC.doFinal(encodedPutPolicy.getBytes()));
            String token = "UPLOAD " + accessKey + ":" + encodedSign + ":" + encodedPutPolicy;
            responsedata.put(TagWords.SUCCESS,true);
            responsedata.put("token",token);
            responsedata.put("bucket", NosKeys.BUCKET);
            responsedata.put("filename",filename);

        } catch (Exception e) {
            responsedata.put(TagWords.SUCCESS,false);
        }
        return Response.success(responsedata);

    }



    @RequestMapping(value = "/ajaxNeteaseFile", method = RequestMethod.POST)
    public ResponseEntity ajaxNeteaseFile(@RequestParam("file") MultipartFile file, @RequestParam("filename") String filename) {
        Map<String,Object> responsedata=new HashMap<>();
        String extName = StaticKey.EMPTY;
        String newFileFullname = StaticKey.EMPTY;// 包含后缀的文件名
        String newFileName = StaticKey.EMPTY;// 没有包含后缀的文件名
        String nowTimeStr = StaticKey.EMPTY;
        String realpath = FileTools.isExistdir();
        SimpleDateFormat sDateFormat;
        Random r = new Random();
        String savePath = request.getSession().getServletContext().getRealPath(
                File.separator);
        savePath = savePath + realpath;
        int rannum = (int) (r.nextDouble() * (99999 - 1000 + 1)) + 10000;
        sDateFormat = new SimpleDateFormat(DateTools.DF_YYYYMMDDHHMMSS);
        nowTimeStr = sDateFormat.format(new Date());
        if (filename.lastIndexOf(TagWords.DOT) >= 0) {
            extName = filename.substring(filename.lastIndexOf(TagWords.DOT));
        }
        // 包含后缀的文件全名
        newFileFullname = nowTimeStr + rannum + extName;
        // 不包含后缀的文件全名
        newFileName = nowTimeStr + rannum;

        //文件的保存地址
        String filePath = savePath + newFileFullname;

        Credentials credentials = new BasicCredentials(NosKeys.ACCESSKEY, NosKeys.ACCESSSECRET);
        NosClient nosClient = new NosClient(credentials);
        nosClient.setEndpoint(NosKeys.ENDPOINT);
        ImgFileBean ifb = new ImgFileBean();
        try {
            if (!file.isEmpty()) {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(savePath + newFileFullname)));
                stream.write(bytes);
                stream.close();
            }

            ifb.setBasepath(BaseTools.getBasePath() + "/");
            String cloudFileKey = realpath + newFileFullname;// 云上的文件名称
            cloudFileKey = cloudFileKey.replace('\\', '/');
            nosClient.putObject(NosKeys.BUCKET, cloudFileKey, new File(filePath));
            response.setStatus(HttpServletResponse.SC_OK);

            ifb.setSucflag(true);
            ifb.setCloudImg(true);
            ifb.setBasepath(StaticKey.EMPTY);
            ifb.setNormalfilepath(NosKeys.PUBLICURL + cloudFileKey);
            responsedata.put(TagWords.IFB, ifb);
        } catch (Exception e) {
            ifb.setSucflag(false);
            ifb.setMsg(e.getMessage());
        }

        return Response.success(responsedata);
    }


    @RequestMapping(value = "/ajaxNeteaseFileVideo", method = RequestMethod.POST)
    public ResponseEntity ajaxNeteaseFileVideo(@RequestParam("file") MultipartFile file, @RequestParam("filename") String filename) {
        Map<String,Object> responsedata=new HashMap<>();
        String extName = StaticKey.EMPTY;
        String newFileFullname = StaticKey.EMPTY;// 包含后缀的文件名
        String newFileName = StaticKey.EMPTY;// 没有包含后缀的文件名
        String nowTimeStr = StaticKey.EMPTY;
        String realpath = FileTools.isExistdir();
        SimpleDateFormat sDateFormat;
        Random r = new Random();
        String savePath = request.getSession().getServletContext().getRealPath(
                File.separator);
        savePath = savePath + realpath;
        int rannum = (int) (r.nextDouble() * (99999 - 1000 + 1)) + 10000;
        sDateFormat = new SimpleDateFormat(DateTools.DF_YYYYMMDDHHMMSS);
        nowTimeStr = sDateFormat.format(new Date());
        if (filename.lastIndexOf(TagWords.DOT) >= 0) {
            extName = filename.substring(filename.lastIndexOf(TagWords.DOT));
        }
        // 包含后缀的文件全名
        newFileFullname = nowTimeStr + rannum + extName;
        // 不包含后缀的文件全名
        newFileName = nowTimeStr + rannum;

        //文件的保存地址
        String filePath = savePath + newFileFullname;

        Credentials credentials = new BasicCredentials(NosKeys.ACCESSKEY, NosKeys.ACCESSSECRET);
        NosClient nosClient = new NosClient(credentials);
        nosClient.setEndpoint(NosKeys.ENDPOINT);
        ImgFileBean ifb = new ImgFileBean();
        try {
            if (!file.isEmpty()) {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(savePath + newFileFullname)));
                stream.write(bytes);
                stream.close();
            }

            ifb.setBasepath(BaseTools.getBasePath() + "/");
            String cloudFileKey = realpath + newFileFullname;// 云上的文件名称
            cloudFileKey = cloudFileKey.replace('\\', '/');
            nosClient.putObject(NosKeys.VIDEOBUCKET, cloudFileKey, new File(filePath));
            response.setStatus(HttpServletResponse.SC_OK);

            ifb.setSucflag(true);
            ifb.setCloudImg(true);
            ifb.setBasepath(StaticKey.EMPTY);
            ifb.setNormalfilepath(NosKeys.PUBLICURL + cloudFileKey);
            ifb.setExtname(extName);
            responsedata.put(TagWords.IFB, ifb);
        } catch (Exception e) {
            ifb.setSucflag(false);
            ifb.setMsg(e.getMessage());
        }

        return Response.success(responsedata);
    }


    @RequestMapping(value = "/ajaxNeteaseFilesBigVideo", method = RequestMethod.POST)
    public ResponseEntity ajaxNeteaseVideoFiles(@RequestParam("file") MultipartFile file, @RequestParam("filename") String filename) {
        Map<String, Object> responsedata = new HashMap<>();

        String extName = StaticKey.EMPTY;
        String newFileFullname = StaticKey.EMPTY;// 包含后缀的文件名
        String newFileName = StaticKey.EMPTY;// 没有包含后缀的文件名
        String nowTimeStr = StaticKey.EMPTY;
        String realpath = FileTools.isExistdir();
        SimpleDateFormat sDateFormat;
        Random r = new Random();
        String savePath = request.getSession().getServletContext().getRealPath(
                File.separator);
        savePath = savePath + realpath;
        int rannum = (int) (r.nextDouble() * (99999 - 1000 + 1)) + 10000;
        sDateFormat = new SimpleDateFormat(DateTools.DF_YYYYMMDDHHMMSS);
        nowTimeStr = sDateFormat.format(new Date());
        if (filename.lastIndexOf(TagWords.DOT) >= 0) {
            extName = filename.substring(filename.lastIndexOf(TagWords.DOT));
        }
        // 包含后缀的文件全名
        newFileFullname = nowTimeStr + rannum + extName;
        // 不包含后缀的文件全名
        newFileName = nowTimeStr + rannum;

        //文件的保存地址
        String filePath = savePath + newFileFullname;
        Credentials credentials = new BasicCredentials(NosKeys.ACCESSKEY,NosKeys.ACCESSSECRET);
        NosClient nosClient = new NosClient(credentials);
        nosClient.setEndpoint(NosKeys.ENDPOINT);
        VideoFileBean ifb = new VideoFileBean();
        ifb.setBasepath(BaseTools.getBasePath() + "/");
        String cloudFileKey = realpath + newFileFullname;// 云上的文件名称
        cloudFileKey = cloudFileKey.replace('\\', '/');


        try {
            if (!file.isEmpty()) {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(savePath + newFileFullname)));
                stream.write(bytes);
                stream.close();
            }
            FileInputStream is = new FileInputStream(new File(savePath + newFileFullname));


            InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(NosKeys.VIDEOBUCKET, cloudFileKey);
            //你还可以在初始化分块上传时，设置文件的Content-Type
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType("application/xml");
            initRequest.setObjectMetadata(objectMetadata);
            InitiateMultipartUploadResult initResult = nosClient.initiateMultipartUpload(initRequest);
            String uploadId = initResult.getUploadId();
            byte[] buf = new byte[4069];
            int readLen =0;
            int buffSize=1024;
            int partIndex=1;
            while ((readLen = is.read(buf,0,buffSize)) != -1 ){
                InputStream partStream = new ByteArrayInputStream(buf);
                nosClient.uploadPart(new UploadPartRequest().withBucketName(NosKeys.VIDEOBUCKET)
                        .withUploadId(uploadId).withInputStream(partStream)
                        .withKey(cloudFileKey).withPartSize(readLen).withPartNumber(partIndex));
                partIndex++;
                //System.out.println(partIndex);
                System.out.println(readLen);
            }
            List<PartETag> partETags = new ArrayList<PartETag>();

            int nextMarker = 0;
            while (true) {
                ListPartsRequest listPartsRequest = new ListPartsRequest(NosKeys.VIDEOBUCKET, cloudFileKey, uploadId);
                listPartsRequest.setPartNumberMarker(nextMarker);
                PartListing partList = nosClient.listParts(listPartsRequest);
                for (PartSummary ps : partList.getParts()) {
                    nextMarker++;
                    partETags.add(new PartETag(ps.getPartNumber(), ps.getETag()));
                }

                if (!partList.isTruncated()) {
                    break;
                }
            }
            CompleteMultipartUploadRequest completeRequest =  new CompleteMultipartUploadRequest(NosKeys.VIDEOBUCKET,cloudFileKey, uploadId, partETags);
            CompleteMultipartUploadResult completeResult = nosClient.completeMultipartUpload(completeRequest);
            response.setStatus(HttpServletResponse.SC_OK);
            ifb.setSucflag(true);
            ifb.setCloudImg(true);
            ifb.setBasepath(StaticKey.EMPTY);
            ifb.setNormalfilepath(NosKeys.PUBLICURL + cloudFileKey);
            ifb.setExtname(extName);
            responsedata.put(TagWords.IFB, ifb);
            is.close();
        } catch (Exception e) {
            ifb.setSucflag(false);
            ifb.setMsg(e.getMessage());
            e.printStackTrace();
        }

        return Response.success(responsedata);

    }



}
